﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace LSA.OnlineResources
{
    public class GoogleSearch : ISearchEngine
    {
        public GoogleSearch(string searchExpression, WebProxy proxySettings)
        {
            Engine = SearchResult.SearchEngine.Google;
            SearchExpression = searchExpression;
            if(client == null)
            {
                //ServicePointManager.MaxServicePoints = int.MaxValue;
                client = new WebClient {Encoding = System.Text.Encoding.UTF8, Proxy = proxySettings};
            }
        }
        
        public GoogleSearch(string searchExpression) : this(searchExpression, null)
        {
        }

        public SearchResult.SearchEngine Engine { get; set; }
        public string SearchExpression { get; set; }

        private static WebClient client;

        public List<SearchResult> Search()
        {
            const string urlTemplate =
                @"http://ajax.googleapis.com/ajax/services/search/web?v=1.0&rsz=large&safe=active&q={0}&start={1}";
            var resultsList = new List<SearchResult>();
            int[] offsets = {0, 8};
            
            foreach (var offset in offsets)
            {
                var searchUrl = new Uri(string.Format(urlTemplate, SearchExpression, offset));
                
                var page = client.DownloadString(searchUrl);
                var o = (JObject) JsonConvert.DeserializeObject(page);

                if(!o["responseData"].Any())
                {
                    throw new WebException("Google returned nothing");
                }
                if (!o["responseData"]["results"].Any())
                {
                    throw new WebException("Google returned nothing");
                }
                var children = o["responseData"]["results"].Children();
                var resultsQuery = children.Select(result => new SearchResult
                                                                 {
                                                                     Url = result.Value<string>("url"),
                                                                     Title = result.Value<string>("title"),
                                                                     Content = result.Value<string>("content"),
                                                                     Engine = Engine
                                                                 });
                resultsList.AddRange(resultsQuery);
            }
            return resultsList;
        }
    }
}
